import React, { Component } from 'react'
import axios from 'axios'
import { Link } from 'react-router-dom'
import { Toast } from 'antd-mobile'
import NavHeader from '../../components/NavHeader'
import './index.scss'
import styles from './index.module.css'
// 覆盖物样式
const labelStyle = {
    cursor: 'pointer',
    border: '0px solid rgb(255, 0, 0)',
    padding: '0px',
    whiteSpace: 'nowrap',
    fontSize: '12px',
    color: 'rgb(255, 255, 255)',
    textAlign: 'center'
}
// 解决脚手架中全局变量访问的问题
const BMap = window.BMapGL
export default class Map extends Component {
    state = {
        houseList: [],
        isShowList: false
    }
    componentDidMount() {
        this.initMap()
    }

    // 初始化地图
    initMap() {
        /* 
          1 获取当前定位城市。
          2 使用地址解析器解析当前城市坐标。
          3 调用 centerAndZoom() 方法在地图中展示当前城市，并设置缩放级别为11。
          4 在地图中展示该城市，并添加比例尺和平移缩放控件。
        */

        // 获取当前定位城市
        const { label, value } = JSON.parse(localStorage.getItem('hkzf_city'))
        // console.log(label, value)

        // 初始化地图实例
        // 注意：在 react 脚手架中全局对象需要使用 window 来访问，否则，会造成 ESLint 校验错误
        const map = new BMap.Map('container')
        this.map = map
        // 设置中心点坐标
        // const point = new window.BMap.Point(116.404, 39.915)

        // 创建地址解析器实例
        const myGeo = new BMap.Geocoder()
        // 将地址解析结果显示在地图上，并调整地图视野
        myGeo.getPoint(
            label,
            async point => {
                if (point) {
                    //  初始化地图
                    map.centerAndZoom(point, 11)
                    // map.addOverlay(new BMap.Marker(point))

                    // 添加常用控件
                    map.addControl(new BMap.ZoomControl())
                    map.addControl(new BMap.ScaleControl())

                    // 调用 renderOverlays 方法
                    this.renderOverlays(value)
                    /* 
                      渲染所有区覆盖物
                    */
                    /* const res = await axios.get(
                      `http://localhost:8080/area/map?id=${value}`
                    )
                    res.data.body.forEach(item => {
                      // 为每一条数据创建覆盖物
                      const {
                        coord: { longitude, latitude },
                        label: areaName,
                        count,
                        value
                      } = item
          
                      // 创建坐标对象
                      const areaPoint = new BMap.Point(longitude, latitude)
                      // 创建覆盖物
                      const label = new BMap.Label('', {
                        position: areaPoint,
                        offset: new BMap.Size(-35, -35)
                      })
          
                      // 给 label 对象添加一个唯一标识
                      label.id = value
          
                      // 设置房源覆盖物内容
                      label.setContent(`
                        <div class="${styles.bubble}">
                          <p class="${styles.name}">${areaName}</p>
                          <p>${count}套</p>
                        </div>
                      `)
          
                      // 设置样式
                      label.setStyle(labelStyle)
          
                      // 添加单击事件
                      label.addEventListener('click', () => {
                        console.log('房源覆盖物被点击了', label.id)
          
                        // 放大地图，以当前点击的覆盖物为中心放大地图
                        map.centerAndZoom(areaPoint, 13)
          
                        // 解决清除覆盖物时，百度地图API的JS文件自身报错的问题
                        setTimeout(() => {
                          // 清除当前覆盖物信息
                          map.clearOverlays()
                        }, 0)
                      })
          
                      // 添加覆盖物到地图中
                      map.addOverlay(label)
                    }) */

                }
            },
            label
        )
        //给地图绑定移动事件
        map.addEventListener('movestart', () => {
            if (this.state.isShowList) {
                this.setState({ isShowList: false })
            }
        })
        // 初始化地图
        // map.centerAndZoom(point, 15)
    }
    // 渲染覆盖物入口
    // 1 接收区域 id 参数，获取该区域下的房源数据
    // 2 获取房源类型以及下级地图缩放级别
    async renderOverlays(id) {
        try {
            //开启loading
            Toast.loading('加载中...', 0, null, false)
            const res = await axios.get(`http://localhost:8080/area/map?id=${id}`)
            Toast.hide()
            const data = res.data.body

            // 调用 getTypeAndZoom 方法获取级别和类型
            const { nextZoom, type } = this.getTypeAndZoom()

            data.forEach(item => {
                // 创建覆盖物
                this.createOverlays(item, nextZoom, type)
            })
        } catch (error) {
            Toast.hide()
            alert("加载有误，嗷~~")
        }
    }
    // 创建覆盖物
    createOverlays(data, zoom, type) {
        const {
            coord: { longitude, latitude },
            label: areaName,
            count,
            value
        } = data
        // 创建坐标对象
        const areaPoint = new BMap.Point(longitude, latitude)

        if (type === 'circle') {
            //区或镇
            this.createCircle(areaPoint, areaName, count, value, zoom)
        } else {
            // 小区
            this.createRect(areaPoint, areaName, count, value)
        }
    }
    getTypeAndZoom() {
        const zoom = this.map.getZoom()
        let nextZoom, type
        if (zoom >= 10 && zoom < 12) {
            //区
            nextZoom = 13;
            type = 'circle'
        } else if (zoom >= 12 && zoom < 14) {
            //镇
            nextZoom = 15;
            type = 'circle'
        } else if (zoom >= 14 && zoom < 16) {
            //小区
            type = 'rect'
        }
        return { nextZoom, type }
    }
    // 创建区、镇覆盖物
    createCircle(point, name, count, id, zoom) {
        // 创建覆盖物
        const label = new BMap.Label('', {
            position: point,
            offset: new BMap.Size(-35, -35)
        })

        // 给 label 对象添加一个唯一标识
        label.id = id

        // 设置房源覆盖物内容
        label.setContent(`
    <div class="${styles.bubble}">
      <p class="${styles.name}">${name}</p>
      <p>${count}套</p>
    </div>
  `)

        // 设置样式
        label.setStyle(labelStyle)

        // 添加单击事件
        label.addEventListener('click', () => {
            // 调用 renderOverlays 方法，获取该区域下的房源数据
            this.renderOverlays(id)

            // 放大地图，以当前点击的覆盖物为中心放大地图
            this.map.centerAndZoom(point, zoom)

            // 解决清除覆盖物时，百度地图API的JS文件自身报错的问题
            setTimeout(() => {
                // 清除当前覆盖物信息
                this.map.clearOverlays()
            }, 0)
        })

        // 添加覆盖物到地图中
        this.map.addOverlay(label)
    }

    // 创建小区覆盖物
    createRect(point, name, count, id) {
        // 创建覆盖物
        const label = new BMap.Label('', {
            position: point,
            offset: new BMap.Size(-50, -28)
        })

        // 给 label 对象添加一个唯一标识
        label.id = id

        // 设置房源覆盖物内容
        label.setContent(`
          <div class="${styles.rect}">
            <span class="${styles.housename}">${name}</span>
            <span class="${styles.housenum}">${count}套</span>
            <i class="${styles.arrow}"></i>
          </div>
        `)

        // 设置样式
        label.setStyle(labelStyle)

        // 添加单击事件
        // 添加单击事件
        label.addEventListener('click', e => {
            /* 
              1 创建 Label 、设置样式、设置 HTML 内容，绑定单击事件。
              
              2 在单击事件中，获取该小区的房源数据。
              3 展示房源列表。
              4 渲染获取到的房源数据。
      
              5 调用地图 panBy() 方法，移动地图到中间位置。
                公式：
                  垂直位移：(window.innerHeight - 330) / 2 - target.clientY
                  水平平移：window.innerWidth / 2 - target.clientX
              6 监听地图 movestart 事件，在地图移动时隐藏房源列表。
            */

            this.getHouseList(id)

            // 获取当前被点击项
            // console.log(e);
            const target = e.domEvent.changedTouches[0]
            this.map.panBy(
                window.innerWidth / 2 - target.clientX,
                (window.innerHeight - 330) / 2 - target.clientY
            )
            // console.log('小区被点击了')
        })
        // 添加覆盖物到地图中
        this.map.addOverlay(label)
    }
    //获取小区覆盖物
    async getHouseList(id) {
        try {
            //开启loading
            Toast.loading('加载中...', 0, null, false)
            const res = await axios.get(`http://localhost:8080/houses?cityId=${id}`)
            Toast.hide()
            this.setState({
                houseList: res.data.body.list,
                isShowList: true
            })
        } catch (error) {
            Toast.hide()
            alert("加载有误，嗷~~")
        }

    }

    rederHousersList() {
        // {/* 房屋结构 */ }

        return this.state.houseList.map(item => (
            <div className={styles.house} key={item.houseCode}>
                <div className={styles.imgWrap}>
                    <img
                        className={styles.img}
                        src={`http://localhost:8080${item.houseImg}`}
                        alt=""
                    />
                </div>
                <div className={styles.content}>
                    <h3 className={styles.title}>{item.title}</h3>
                    <div className={styles.desc}>{item.desc}</div>
                    <div>
                        {item.tags.map((tag, index) => {
                            const tagClass = 'tag' + (index + 1)
                            return (
                                (
                                    <span
                                        className={[styles.tag, styles[tagClass]].join(' ')}
                                        key={tag}
                                    >
                                        {tag}
                                    </span>
                                )
                            )
                        })}
                    </div>
                    <div className={styles.price}>
                        <span className={styles.priceNum}>{item.price}</span> 元/月
                    </div>
                </div>
            </div>
        ))

    }
    render() {
        return (
            <div className='map'>
                {/* 顶部导航栏组件 */}
                <NavHeader>地图找房</NavHeader>
                {/* 地图容器元素 */}
                <div id="container" />
                {/* 房源列表 */}
                {/* 添加 styles.show 展示房屋列表 */}
                <div
                    className={[
                        styles.houseList,
                        this.state.isShowList ? styles.show : ''
                    ].join(' ')}
                >
                    <div className={styles.titleWrap}>
                        <h1 className={styles.listTitle}>房屋列表</h1>
                        <Link className={styles.titleMore} to="/home/list">
                            更多房源
                        </Link>
                    </div>

                    <div className={styles.houseItems}>
                        {this.rederHousersList()}
                    </div>
                </div>
            </div>
        )
    }
}